package es

type H map[string]interface{}

type BoolQuery struct {
	H
	must   []H
	filter []H
}

func NewBoolQuery() *BoolQuery {
	return &BoolQuery{
		H: H{"query": H{
			"bool": H{},
		}},
	}
}

func (b *BoolQuery) From(v int) *BoolQuery {
	b.H["from"] = v
	return b
}

func (b *BoolQuery) Size(v int) *BoolQuery {
	b.H["size"] = v
	return b
}

func (b *BoolQuery) Must(v ...H) *BoolQuery {
	for _, h := range v {
		b.must = append(b.must, h)
	}
	b.H["query"].(H)["bool"].(H)["must"] = b.must
	return b
}

func (b *BoolQuery) Filter(v ...H) *BoolQuery {
	for _, h := range v {
		b.filter = append(b.filter, h)
	}
	b.H["query"].(H)["bool"].(H)["filter"] = b.filter
	return b
}

type MultiMatchQuery struct {
	H
}

func NewMultiMatchQuery(fieldName string, fields ...string) *MultiMatchQuery {
	return &MultiMatchQuery{
		H: H{
			"multi_match": H{
				"query":  fieldName,
				"fields": fields,
			},
		},
	}
}

type RangeQuery struct {
	field string
	H
}

func NewRangeQuery(field string) *RangeQuery {
	return &RangeQuery{
		field: field,
		H: H{
			"range": H{
				field: H{},
			},
		},
	}
}

func (r *RangeQuery) Gte(v interface{}) *RangeQuery {
	r.H["range"].(H)[r.field].(H)["gte"] = v
	return r
}

func (r *RangeQuery) Lte(v interface{}) *RangeQuery {
	r.H["range"].(H)[r.field].(H)["lte"] = v
	return r
}

type TermQuery struct {
	H
}

func NewTermQuery(fieldName string, value interface{}) *TermQuery {
	return &TermQuery{
		H: H{"term": H{
			fieldName: value,
		}},
	}
}

type TermsQuery struct {
	H
}

func NewTermsQuery(fieldName string, values ...interface{}) *TermsQuery {
	return &TermsQuery{
		H: H{"terms": H{
			fieldName: values,
		}},
	}
}
